<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>李大刚的铁窗泪</title>
    <link rel="stylesheet" href="https://unpkg.zhimg.com/element-ui@2.15.9/lib/theme-chalk/index.css"></link>
    <style>
        body {
            background-color: #eee;
            color: #333;
            box: margin 0 auto;
        }
        .classPic {
            margin-top: 5px;
            width: 20px;
            height: 20px;
            line-height: 20px;
            --size: 20;
            object-fit: cover;
            border: 1px solid #555;
            float: left;
            margin-right: 6px;
            margin-left: 2px;
            object-position: -160px 0px;
        }
        .box-card {
            margin-top: 15px;
            width: 960px;
        }
        .line-div {
            display:inline-block;
            height: 22px;
            color: white;
            text-align: center;
            line-height: 24px;
        }
    </style>
</head>

<script src="https://unpkg.zhimg.com/vue@2.5.22"></script>
<script src="https://unpkg.zhimg.com/element-ui@2.15.9"></script>
<script src="https://unpkg.zhimg.com/axios@0.26.0"></script>
<script src="https://unpkg.com/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
<script type="text/javascript">
    var xlsx = function (data, settings) {
        if (settings === void 0) {
            settings = {}
        }
        var extraLength = settings.extraLength || 1;
        var writeOptions = settings.writeOptions || {};
        var wb = XLSX.utils.book_new();
        data.forEach(function (actualSheet, actualIndex) {
            var excelColumns = 0;
            var excelContent = [];
            var excelIndexes = [];
            actualSheet.content.forEach(function (el1) {
                var obj = {};
                actualSheet.columns.forEach(function (el2, in2) {
                    var val = typeof el2.value === "function" ? el2.value(el1) : el1[el2.value];
                    obj[el2.label] = val;
                    excelColumns = in2 + 1
                });
                excelContent.push(obj)
            });
            var newSheet = XLSX.utils.json_to_sheet(excelContent);
            {
                var rangeOfColumns = XLSX.utils.decode_range(newSheet["!ref"] || "");
                for (var C = rangeOfColumns.s.c; C <= rangeOfColumns.e.c; C++) {
                    var address = XLSX.utils.encode_col(C) + "1";
                    excelIndexes.push(address)
                }
            }
            newSheet["!cols"] = [];
            var whileLoop = 0;
            while (whileLoop < excelColumns) {
                var xx = excelIndexes[whileLoop];
                var size = {width: newSheet[xx].v.length + extraLength};
                for (var keyIndex in newSheet) {
                    if (newSheet.hasOwnProperty(keyIndex) && xx.charAt(0) === keyIndex.charAt(0) && keyIndex.length === xx.length) {
                        var consideredElement = newSheet[keyIndex].v;
                        if (typeof consideredElement === "number") consideredElement = "" + consideredElement;
                        if (consideredElement && consideredElement.length >= size.width) size.width = consideredElement.length + extraLength
                    }
                }
                newSheet["!cols"].push(size);
                whileLoop++
            }
            XLSX.utils.book_append_sheet(wb, newSheet, "" + (actualSheet.sheet || "Sheet " + (actualIndex + 1)))
        });
        return writeOptions.type == "buffer" ? XLSX.write(wb, writeOptions) : XLSX.writeFile(wb, (settings.fileName || "Spreadsheet") + ".xlsx", writeOptions)
    };
</script>
<script src=""></script>

<body>
<div id="app">
    <template>
        <el-container>
            <el-main>
                <div>
                    <span style="color: #606266">选定牢友资料</span>

                    <el-form label-width="120px" size="small">
                        <el-form-item label="坐牢模式">
                            <el-radio-group size="small" fill="#F56C6C" v-model="input.modeLabel">
                                <el-radio-button

                                        v-for="item in consts.modes"
                                        style="margin: 0px 1px"
                                        :key="item.value"
                                        :disabled="item.disabled"
                                        :label="item.label"
                                        :value="item.value">
                                </el-radio-button>
                            </el-radio-group>
                        </el-form-item>
                        <el-form-item label="坐牢优先级">
                            <el-radio-group size="small" fill="#F56C6C" v-model="input.priLabel">
                                <el-radio-button
                                        size="small" type="danger"
                                        style="margin: 0px 1px"
                                        v-for="item in consts.pris"
                                        :key="item.value"
                                        :disabled="item.disabled"
                                        :label="item.label"
                                        :value="item.value">
                                </el-radio-button>
                            </el-radio-group>
                        </el-form-item>
                        <el-form-item label="坐牢日期">

                            <el-checkbox-group size="small" fill="#F56C6C" v-model="input.weekday">
                                <el-checkbox-button
                                        size="small" type="danger"
                                        style="margin: 0px 1px"
                                        v-for="item in consts.weekdays"
                                        :key="item.value"
                                        :label="item.label">
                                </el-checkbox-button>
                            </el-checkbox-group>
                        </el-form-item>
                        <el-form-item label="牢友资料">
                            <el-upload
                                    style="width:300px"
                                    ref="importRef"
                                    action="/doNothing"
                                    name="file"
                                    :file-list="input.fileList"
                                    :limit="1"
                                    :on-error="importError"
                                    :on-success="importSuccess"
                                    :on-exceed="importReplace"
                                    :on-change="changeUploadFile"
                                    :on-remove="changeUploadFile"
                                    :before-upload="parseFile"
                                    :http-request="analyse"
                                    :auto-upload="false">
                                <el-button slot="trigger" size="small" type="danger">选择文件</el-button>
                                <el-button size="small" type="danger" @click="clickStart" :disabled="!fileReady" :loading="oploading">分析牢友资料</el-button>
                                <div style="display: inline-block" slot="tip" style="color:darkgray;" class="el-upload__tip">
                                </div>
                            </el-upload>
                        </el-form-item>
                    </el-form>
                    <div v-if="anaReady">
                        <el-card class="box-card">
                            <div slot="header" class="clearfix">
                                <span>总览</span>
                            </div>
                            <el-form label-width="50px">
                                <el-form-item

                                        v-for="item in info.overview.view"
                                        :key="item.val"
                                        :label="item.label">
                                    <div style="display: inline-block;width: 90%;margin: 0 40px 0 20px; ">
                                        <div
                                                class="line-div"
                                                v-for="elite in consts.intensityColor"
                                                v-if="item.ratingArea[5 - elite.point] > 0"
                                                :style="computeElite(elite,item)">
                                            {{ item.ratingArea[5 - elite.point] }}人
                                        </div>
                                    </div>
                                    <div v-for="classObj in item.classList" style="display:inline-block; margin: 0 15px;width: 180px">
                                        <el-tag
                                                style="margin: 5px;width: 120px"
                                                :key="classObj.class"
                                                :color="classObj.classColor"
                                                effect="dark">
                                            <img class="classPic" :src="consts.classPic.url" :style="classObj.styleStr">
                                            <span v-if="classObj.classColor !== '#F0EBE0' && classObj.classColor !== '#FFF468'" style="margin-left: 2px;color: #fff">{{ classObj.class }}</span>
                                            <span v-else style="margin-left: 2px;color: #000">{{ classObj.class }}</span>
                                        </el-tag>
                                        <el-badge style="margin-top: 5px; line-height: 20px;" type="success" class="mark" :value="' x ' + classObj.count" />
                                    </div>
                                    <el-divider></el-divider>
                                </el-form-item>
                                <el-form-item>
                                    <el-button style="" size="small" type="danger" @click="click2Jail" :disabled="!anaReady" >开始构建你的专属牢笼</el-button>
                                </el-form-item>
                            </el-form>
                        </el-card>
                    </div>
                    <div v-if="teamReady">
                        <el-card
                                v-for="team in output.teams"
                                class="box-card">
                            <div slot="header" class="clearfix">
                                <span>{{ team.name + ' ( ' + team.teamPlayerCount + '人 )' }}</span>
                            </div>

                            <el-form label-width="50px">
                                <el-form-item
                                        v-for="item in info.overview.view"
                                        :key="item.val"
                                        :label="item.label">
                                    <div v-for="player in team[item.val]" style="display:inline-block; margin: 0 15px;width: 180px">
                                        <el-tag
                                                style="margin: 5px;width: 120px"
                                                :key="player.class"
                                                :color="player.classColor"
                                                effect="dark">
                                            <img class="classPic" :src="consts.classPic.url" :style="player.styleStr">
                                            <span v-if="player.classColor !== '#F0EBE0' && player.classColor !== '#FFF468'" style="margin-left: 2px;color: #fff">{{ player.char }}</span>
                                            <span v-else style="margin-left: 2px;color: #000">{{ player.char }}</span>
                                        </el-tag>
                                    </div>
                                    <el-divider></el-divider>
                                </el-form-item>
                            </el-form>
                        </el-card>
                        <el-card
                                class="box-card">
                            <div slot="header" class="clearfix">
                                <span>没团的孤儿</span>
                            </div>

                            <el-form label-width="50px">
                                <el-form-item
                                        v-for="item in info.overview.view"
                                        :key="item.val"
                                        v-if="output.noTeams[item.val].length > 0"
                                        :label="item.label">
                                    <div v-for="player in output.noTeams[item.val]" style="display:inline-block; margin: 0 15px;width: 180px">
                                        <el-tag
                                                style="margin: 5px;width: 120px"
                                                :key="player.class"
                                                :color="player.classColor"
                                                effect="dark">
                                            <img class="classPic" :src="consts.classPic.url" :style="player.styleStr">
                                            <span v-if="player.classColor !== '#F0EBE0' && player.classColor !== '#FFF468'" style="margin-left: 2px;color: #fff">{{ player.char }}</span>
                                            <span v-else style="margin-left: 2px;color: #000">{{ player.char }}</span>
                                        </el-tag>
                                    </div>
                                    <el-divider></el-divider>
                                </el-form-item>
                            </el-form>
                        </el-card>
                        <el-row>
                            <el-button style="" size="small" type="danger" @click="click2Save" :disabled="!anaReady" >保存</el-button>
                        </el-row>
                    </div>
            </el-main>
        </el-container>
    </template>
</div>
</body>
<script type="text/javascript">
    let app = new Vue({
        el: '#app',
        data() {
            let defaultInfo = {
                class_intensity_list: [],
                player_intensity_list: [],
                char_intensity_list: [],
                party_intensity_list: [],
                wcl_intensity_list: [],
                stable_intensity_list: [],
                point_default: {},
                players: [],

                overview: {
                    total: 0,
                    view: [
                        {val: 'tank', label: '坦克', total: 0, ratingArea: [0, 0, 0, 0, 0], classList: []},
                        {val: 'heal', label: '治疗', total: 0, ratingArea: [0, 0, 0, 0, 0], classList: []},
                        {val: 'mdps', label: '近战', total: 0, ratingArea: [0, 0, 0, 0, 0], classList: []},
                        {val: 'rdps', label: '远程', total: 0, ratingArea: [0, 0, 0, 0, 0], classList: []},
                    ],
                    tank: [],
                    heal: [],
                    mdps: [],
                    rdps: [],
                },
            };

            return {
                consts: {
                    modes: [
                        {label: '1-开荒无尽牢', value: 1, disabled: false},
                        {label: '2-刷分随意牢', value: 2, disabled: true},
                        {label: '3-摆烂躺平牢', value: 3, disabled: true},
                    ],
                    pris: [
                        {label: '1-大刚的爹优先', value: 1, disabled: false},
                        {label: '2-刷分狗优先', value: 2, disabled: true},
                        {label: '3-抱团狗优先', value: 3, disabled: true},
                    ],
                    weekdays: [
                        {label: '周四', value: 4},
                        {label: '周五', value: 5},
                        {label: '周六', value: 6},
                        {label: '周日', value: 7},
                        {label: '周一', value: 1},
                        {label: '周二', value: 2},
                        {label: '周三', value: 3},
                    ],
                    player_sheet: '人员表',
                    char_sheet: '职业强度对比',
                    intensity_sheet: '评级标准',
                    label0: {
                        'char': '角色名',
                        'class': '职业专精',
                        'skip': '能不能打',
                        'player': '人员',
                        'isdad': '大刚的爹',
                        'player_intensity': '人员强度',
                        'char_intensity': '角色强度',
                        'party_intensity': '小团体依赖度',
                        'wcl_intensity': '刷分强度',
                        'stable_intensity': '稳定情况',
                        'sparty': '小团队标记',
                        'play_day': '可打的时间'
                    },
                    label1: {
                        'class': '职业专精',
                        'point': '打分',
                        'position': '位置',
                        'classColor': '颜色',
                        'classPic': '专精图标',
                        'leastCount': '最少数量',
                    },
                    label2: {
                        'point': '分值',
                        'player_intensity': '人员强度',
                        'char_intensity': '角色强度',
                        'party_intensity': '小团体依赖度',
                        'wcl_intensity': '刷分强度',
                        'stable_intensity': '稳定情况',
                    },
                    classPic: {
                        url: 'https://assets.rpglogs.cn/img/warcraft/icons/actors.jpg?v=12',
                        classes: [],
                    },
                    intensityColor: [
                        {point: 5, color: '#ff8000'},
                        {point: 4, color: '#a335ee'},
                        {point: 3, color: '#0070ff'},
                        {point: 2, color: '#1eff00'},
                        {point: 1, color: '#666'},
                    ],
                    raidMarkEliteCount: 2,
                    raidMarkElite: [
                        {'position': 'tank', count: 2},
                        {'position': 'heal', count: 5},
                    ],
                    raidMark: [
                        {'position': 'tank', count: 3},
                        {'position': 'heal', count: 6},
                    ],
                    healSameMax: 3,
                    dpsSameMax: 3,
                    leastClass: {},
                },
                input: {
                    fileList: [],
                    modeLabel: '1-开荒无尽牢',
                    priLabel: '1-大刚的爹优先',
                    weekday: ['周四','周五','周六','周日']
                },
                output: {
                    teams: [],
                    noTeams: {
                        tank: [],
                        heal: [],
                        mdps: [],
                        rdps: [],
                    },
                },
                defaultInfo: JSON.parse(JSON.stringify(defaultInfo)),
                info: defaultInfo,
                oploading: false,
                fileReady: false,
                anaReady: false,
                validCc: false,
                teamReady: false,
            }
        },
        created() {

        },
        methods: {
            analyse(fileObj) {
                if (this.validCc) {
                    const qStr = decodeURIComponent((new RegExp('[?|&]' + 'ecode' + '=' + '([^&;]+?)(&|#|;|$)').exec(window.location.href) || [, ""])[1].replace(/\+/g, '%20')) || null
                    if (qStr !== this.getCc()) {
                        this.$message.info("你的码失效了哦，找李大刚再要一个吧！");
                        return;
                    }
                }
                let _self = this;
                _self.anaReady = false;
                _self.teamReady = false;
                var reader = new FileReader();
                // 重制
                this.info = JSON.parse(JSON.stringify(this.defaultInfo));
                //5.绑定FileReader对象读取文件对象时的触发方法
                reader.onload = function(e) {
                    //7.获取文件二进制数据流
                    var data = e.currentTarget.result;
                    //8.利用XLSX解析二进制文件为xlsx对象
                    try {
                        var wb = XLSX.read(data, {type: 'binary'})
                    } catch (e) {
                        console.log(e);
                        _self.$message.info("能选个正常点的文件吗")
                        return;
                    }
                    if (!wb.SheetNames || wb.SheetNames.length === 0) {
                        _self.$message.info("能选个正常点的文件吗")
                        return;
                    }
                    if (!wb.SheetNames.includes(_self.consts.player_sheet) || !wb.SheetNames.includes(_self.consts.char_sheet) || !wb.SheetNames.includes(_self.consts.intensity_sheet)) {
                        _self.$message.info("能选个正常点的文件吗")
                        return;
                    }
                    try {
                        _self.parseIntensity(XLSX.utils.sheet_to_json(wb.Sheets[_self.consts.intensity_sheet]));
                        _self.parseChar(XLSX.utils.sheet_to_json(wb.Sheets[_self.consts.char_sheet]));
                        _self.parsePlayer(XLSX.utils.sheet_to_json(wb.Sheets[_self.consts.player_sheet]));

                        // 计算团队总览数据
                        _self.calcOverview();
                        _self.anaReady = true;
                    } catch (e) {
                        console.log(e);
                        _self.$message.info("能选个正常点的文件吗")
                    }
                };
                try {
                    reader.readAsBinaryString(fileObj.file);
                } catch (e) {
                    console.log(e);
                    _self.$message.info("能选个正常点的文件吗")
                }
            },
            getCc() {
                const today = new Date();
                const dStr = `${today.getFullYear() + '-' + (today.getMonth() + 1) + '-' + today.getDate()}`;
                var rdd = '^-^^^^^0123456789_';
                let c = 1;
                for (let i = 0; i < dStr.length;i++) {
                    c *= rdd.indexOf(dStr.charAt(i)) + 23;
                }
                return ("" + c).substr(1, 6);
            },
            parseIntensity(data) {
                data.forEach(o => {
                    const point = o[this.consts.label2.point];
                    if (point === '默认值') {
                        this.info.point_default.player_intensity = o[this.consts.label2.player_intensity];
                        this.info.point_default.char_intensity = o[this.consts.label2.char_intensity];
                        this.info.point_default.party_intensity = o[this.consts.label2.party_intensity];
                        this.info.point_default.wcl_intensity = o[this.consts.label2.wcl_intensity];
                        this.info.point_default.stable_intensity = o[this.consts.label2.stable_intensity];
                    } else {
                        this.info.player_intensity_list.push({
                            label: o[this.consts.label2.player_intensity],
                            point: point,
                        });
                        this.info.char_intensity_list.push({
                            label: o[this.consts.label2.char_intensity],
                            point: point,
                        });
                        this.info.party_intensity_list.push({
                            label: o[this.consts.label2.party_intensity],
                            point: point,
                        });
                        this.info.wcl_intensity_list.push({
                            label: o[this.consts.label2.wcl_intensity],
                            point: point,
                        });
                        this.info.stable_intensity_list.push({
                            label: o[this.consts.label2.stable_intensity],
                            point: point,
                        });
                    }
                });
            },
            parseChar(data) {
                data.forEach(o => {
                    let obj = {};
                    for (const key in this.consts.label1) {
                        const excelKey = this.consts.label1[key];
                        obj[key] = o[excelKey];
                    }
                    // 计算出职业图片样式
                    obj.styleStr = `object-position: -${(parseInt(obj.classPic) - 1) * 20}px 0px`;
                    obj.count = 0;
                    this.info.class_intensity_list.push(obj);
                });

            },
            parsePlayer(data) {
                data.forEach(o => {
                    let obj = {};
                    for (const key in this.consts.label0) {
                        const excelKey = this.consts.label0[key];
                        let val = o[excelKey];
                        if (!val) {
                            if (this.info.point_default[key]) {
                                val = this.info.point_default[key];
                            } else {
                                val = '';
                            }
                        }
                        obj[key] = val;
                    }
                    if (obj.skip !== '否') {
                        obj.isdad = obj.isdad === '是';
                        // 得到角色定位
                        let find = this.info.class_intensity_list.find(o => o.class === obj['class']);
                        if (find) {
                            find.count += 1;
                            obj['position'] = find.position;
                            obj['classColor'] = find.classColor;
                            obj['styleStr'] = find.styleStr;
                            // 计算成员评分
                            this.calcPoint(obj, find);

                            this.info.overview[find.position].push(obj);

                            // 得到角色专精图标
                            this.info.players.push(obj);
                        }
                    }
                });

            },
            calcPoint(player, classIntensity) {
                const classPoint = classIntensity ? classIntensity.point : 3;
                // 权重分配: 专精强度20% -技师强度50% - 装备强度30%
                player.rating = (classPoint * 0.2
                    + player.player_intensity * 0.5
                    + player.char_intensity * 0.3) * 20;
                let intensity;
                if (player.rating < 30) {
                    intensity = this.consts.intensityColor[4];
                } else if (player.rating < 50) {
                    intensity = this.consts.intensityColor[3];
                } else if (player.rating < 70) {
                    intensity = this.consts.intensityColor[2];
                } else if (player.rating < 90) {
                    intensity = this.consts.intensityColor[1];
                } else {
                    intensity = this.consts.intensityColor[0];
                }
                player.ratingColor = intensity.color;
                player.point = intensity.point
            },
            calcOverview() {
                this.info.overview.view.forEach(viewObj => {
                    this.overviewDeal(viewObj);
                });
            },
            overviewDeal(viewObj) {
                const kind = viewObj.val;
                this.info.overview[kind].forEach(o => {
                    let classFind = viewObj.classList.find(p => p['class'] === o['class']);
                    if (!classFind) {
                        const class_intensity = this.info.class_intensity_list.find(p => p['class'] === o['class']);
                        classFind = {...class_intensity, count: 0};
                        viewObj.classList.push(classFind);
                    }
                    viewObj.ratingArea[5 - o.point] += 1;
                    classFind.count += 1;
                    viewObj.total += 1;
                });
                viewObj.classList.sort((a, b) => {return b.count - a.count});
            },
            parseFile() {
            },
            clickStart() {
                this.$refs['importRef'].submit();
            },
            importError() {},
            importSuccess() {},
            importReplace(files, fileList) {
                this.doReplace(files, fileList, 'importRef');
            },
            doReplace(files, fileList, refName) {
                this.$set(fileList[0], 'raw', files[0]);
                this.$set(fileList[0], 'name', files[0].name);
                this.$refs[refName].clearFiles();//清除文件
                this.$refs[refName].handleStart(files[0]);//选择文件后的赋值方法
            },
            changeUploadFile(files, fileList) {
                this.fileReady = this.$refs['importRef']
                    && this.$refs['importRef']._data
                    && this.$refs['importRef']._data.uploadFiles
                    && this.$refs['importRef']._data.uploadFiles.length > 0;
            },
            computeElite(elite, viewObj) {
                const ratingCount = viewObj.ratingArea[5 - elite.point];
                const total = viewObj.ratingArea.reduce((a, b) => a+b);
                const percent = Math.round(1000 * ratingCount / total) / 10;
                const hasPlayerStyle = ''//ratingCount > 0 ? 'min-width: 60px;' : '';
                return `${hasPlayerStyle} width: ${percent}%; background-color: ${elite.color}`;
            },
            parseWeek(weekDay) {
                return this.consts.weekdays.find(o => o.label === weekDay).value;
            },
            click2Jail() {
                const teamTankNeedElite = this.consts.raidMarkElite.find(o => o.position === 'tank').count;
                const teamHealNeedElite = this.consts.raidMarkElite.find(o => o.position === 'heal').count;
                const teamTankNeed = this.consts.raidMark.find(o => o.position === 'tank').count;
                const teamHealNeed = this.consts.raidMark.find(o => o.position === 'heal').count;
                const tankView = this.info.overview.view.find(o => o.val === 'tank');
                const healView = this.info.overview.view.find(o => o.val === 'heal');
                const teamCount = this.input.weekday.length;
                const eliteTeamCount = teamCount > this.consts.raidMarkEliteCount ? this.consts.raidMarkEliteCount : teamCount;
                const loserTeamCount = teamCount > this.consts.raidMarkEliteCount ? (teamCount - this.consts.raidMarkEliteCount) : 0;
                const leastTankNeed = loserTeamCount * teamTankNeed + eliteTeamCount * teamTankNeedElite - 2
                const leastHealNeed = loserTeamCount * teamHealNeed + eliteTeamCount * teamHealNeedElite - 4
                if (tankView.total < leastTankNeed) {
                    this.$message.info(`你就排了${tankView.total}个T，想打${teamCount}个团？你打NMLGB`);
                    return;
                }
                if (healView.total < leastHealNeed) {
                    this.$message.info(`你就排了${tankView.total}个奶，想打${teamCount}个团？你打NMLGB`);
                    return;
                }
                let teams = [];
                for (let i = 0; i < teamCount; i++) {
                    const isElite = i < eliteTeamCount;
                    teams.push({
                        name: this.input.weekday[i] + '团',
                        // 1-7，代表是哪个团
                        date: this.parseWeek(this.input.weekday[i]),
                        teamPlayerCount: 0,
                        intensity: 0,
                        tank_intensity: 0,
                        heal_intensity: 0,
                        dps_intensity: 0,
                        isElite: isElite,
                        tankNeedCount: isElite ? teamTankNeedElite : teamTankNeed,
                        healNeedCount: isElite ? teamHealNeedElite : teamHealNeed,
                        dpsNeedCount: 25 - (isElite ? (teamTankNeedElite + teamHealNeedElite) : (teamTankNeed, teamHealNeed)),
                        // 字符串，已有人员名，防止把一个人的角色排到同一天
                        player: [],
                        // 字符串，已有小团体名，给抱团狗一个顺序排列
                        sparty: [],
                        tank: [],
                        heal: [],
                        mdps: [],
                        rdps: [],
                    });
                }
                let info = this.copyAll(this.info)
                const tanks = info.overview.tank;
                const heals = info.overview.heal;
                const mdpss = info.overview.mdps;
                const rdpss = info.overview.rdps;
                const dpss = [...mdpss, ...rdpss]

                // 1-优先排最强阵容，2-优先排最强且打wcl分的人，3-优先保持每个团战斗力均衡
                const mode = this.consts.modes.find(o => o.label === this.input.modeLabel).value;
                // 1-最高优先级按一团老熟人来操作，2-刷分的人全部排进第一个团，3-最大限度满足想一起玩的小团体在一起打
                const pri = this.consts.pris.find(o => o.label === this.input.priLabel).value;
                this.sortPlayers(tanks, mode, pri);
                this.sortPlayers(heals, mode, pri);
                this.sortPlayers(mdpss, mode, pri);
                this.sortPlayers(rdpss, mode, pri);
                this.sortPlayers(dpss, mode, pri);

                // 最先把大刚的爹排进去
                const dadPlayers = info.players.filter(p => !p.choosed && p.isdad);
                this.sortPlayers(dadPlayers, mode, pri);
                dadPlayers.forEach(p => {
                    teams.some(t => {
                        let posCountNow = t[p.position].length;
                        let posNeedCount;
                        if (p.position === 'tank') {
                            posNeedCount = t.tankNeedCount;
                        } else if (p.position === 'heal') {
                            posNeedCount = t.healNeedCount;
                        } else {
                            posNeedCount = t.dpsNeedCount;
                        }
                        if (posCountNow < t.tankNeedCount && (!p.player || !t.player.includes(p.player))) {
                            t[p.position].push(p);
                            p.player && t.player.push(p.player);
                            p.sparty && t.sparty.push(p.sparty);
                            p.choosed = true;
                            posCountNow++;
                            // 中断查找
                            if (posCountNow === posNeedCount) {
                                return true;
                            }
                        } else {
                            return true;
                        }
                        return false;
                    });

                })

                // 先排必须有的职业
                const mustClasses = info.class_intensity_list.filter(o => o.leastCount && o.leastCount > 0);
                teams.forEach(t => {
                    mustClasses.forEach(mc => {
                        const leastCount = mc.leastCount;
                        let added = 0;
                        const classPlayers = info.players.filter(p => !p.choosed && p['class'] === mc['class'])
                        this.sortPlayers(classPlayers, mode, pri);
                        classPlayers.some(p => {
                            let posCountNow = t[p.position].length;
                            let posNeedCount;
                            if (p.position === 'tank') {
                                posNeedCount = t.tankNeedCount;
                            } else if (p.position === 'heal') {
                                posNeedCount = t.healNeedCount;
                            } else {
                                posNeedCount = t.dpsNeedCount;
                            }
                            if (posCountNow < t.tankNeedCount && (!p.player || !t.player.includes(p.player))) {
                                t[p.position].push(p);
                                p.player && t.player.push(p.player);
                                p.sparty && t.sparty.push(p.sparty);
                                p.choosed = true;
                                added++;
                                // 中断查找
                                if (added === leastCount) {
                                    return true;
                                }
                            }
                            return false;
                        });
                    });

                });

                // 先排T
                tanks.forEach(o => {
                    teams.some(t => {
                        if (!o.choosed && t.tank.length < t.tankNeedCount && (!o.player || !t.player.includes(o.player))) {
                            let classes = t[o.position].map(a => a.class);
                            if (!classes.includes(o.class)) {
                                t.tank.push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                        }
                        return false;
                    });
                })
                // 判断各个团的T是否满了
                let reLoopTeams = teams.filter(t => t.tank.length < t.tankNeedCount);
                if (reLoopTeams.length > 0) {
                    tanks.filter(o => !o.choosed).forEach(o => {
                        reLoopTeams.some(t => {
                            if (t.tank.length < t.tankNeedCount && (!o.player || !t.player.includes(o.player))) {
                                t.tank.push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                            return false;
                        });
                    });
                }

                // 排治疗
                heals.forEach(o => {
                    teams.some(t => {
                        if (!o.choosed && t.heal.length < t.healNeedCount && (!o.player || !t.player.includes(o.player))) {
                            let classes = t[o.position].map(a => a.class);
                            if (!classes.includes(o.class)) {
                                t.heal.push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                        }
                        return false;
                    });
                })
                // 判断各个团的治疗是否满了
                reLoopTeams = teams.filter(t => t.heal.length < t.healNeedCount);
                if (reLoopTeams.length > 0) {
                    heals.filter(o => !o.choosed).forEach(o => {
                        reLoopTeams.some(t => {
                            if (t.heal.length < t.healNeedCount && (!o.player || !t.player.includes(o.player))) {
                                t.heal.push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                            return false;
                        });
                    });
                }

                // 排dps
                dpss.forEach(o => {
                    teams.some(t => {
                        if (!o.choosed && (t.mdps.length + t.rdps.length) < t.dpsNeedCount && (!o.player || !t.player.includes(o.player))) {
                            let classMap = {};
                            t[o.position].forEach(a => {
                                classMap[a.class] = classMap[a.class] ? 1 : (classMap[a.class] + 1);
                            });
                            if (!classMap[o.class] || classMap[o.class] < this.consts.dpsSameMax) {
                                t[o.position].push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                        }
                        return false;
                    });
                })
                // 判断各个团的dps是否满了
                reLoopTeams = teams.filter(t => (t.mdps.length + t.rdps.length) < t.dpsNeedCount);
                if (reLoopTeams.length > 0) {
                    dpss.filter(o => !o.choosed).forEach(o => {
                        reLoopTeams.some(t => {
                            if ((t.mdps.length + t.rdps.length) < t.dpsNeedCount && (!o.player || !t.player.includes(o.player))) {
                                t[o.position].push(o);
                                o.player && t.player.push(o.player);
                                o.sparty && t.sparty.push(o.sparty);
                                o.choosed = true;
                                // 中断查找
                                return true;
                            }
                            return false;
                        });
                    });
                }

                teams.forEach(t => {
                    let tankRatings = t.tank.reduce((a, b) => a.rating + b.rating);
                    let healRatings = t.heal.reduce((a, b) => a.rating + b.rating);
                    let dpsAll = [...t.mdps,...t.rdps];
                    let dpsRatings = dpsAll.length > 0 ? dpsAll.reduce((a, b) => a.rating + b.rating) : 0;
                    t.tank_intensity = t.tank.length > 0 ? Math.round(10 * tankRatings / t.tank.length) / 10 : 0;
                    t.heal_intensity = t.heal.length > 0 ? Math.round(10 * healRatings / t.heal.length) / 10 : 0;
                    t.dps_intensity = (t.mdps.length + t.rdps.length) > 0 ? Math.round(10 * dpsRatings / (t.mdps.length + t.rdps.length > 0)) / 10 : 0;
                    let teamPlayerCount = t.tank.length + t.heal.length + t.mdps.length + t.rdps.length;
                    t.teamPlayerCount = teamPlayerCount;
                    t.intensity = t.player.length > 0 ? Math.round(10 * (tankRatings + healRatings + dpsRatings) / teamPlayerCount) / 10 : 0;
                });

                this.output.teams = teams;
                this.output.noTeams = {
                    tank: tanks.filter(o => !o.choosed),
                    heal: heals.filter(o => !o.choosed),
                    mdps: mdpss.filter(o => !o.choosed),
                    rdps: rdpss.filter(o => !o.choosed),
                }

                this.teamReady = true;
            },
            sortPlayers(players, mode, pri) {
                players.sort((a, b) => {
                    if (a.isdad !== b.isdad) {
                        return a.isdad ? -1 : 1;
                    } else {
                        return b.rating - a.rating;
                    }
                });
            },
            copyAll(data) {
                return JSON.parse(JSON.stringify(data));
            },
            click2Save() {
                this.$message.info("还在施工，别点了")
            }
        }
    });
</script>
</html>